import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';
import { FBXLoader } from 'three/addons/loaders/FBXLoader.js';
import { OBJLoader } from 'three/addons/loaders/OBJLoader.js';
import { PLYLoader } from 'three/addons/loaders/PLYLoader.js';

export class ModelLoader {
    constructor() {
        // GLTF/GLB加载器
        this.gltfLoader = new GLTFLoader();
        this.dracoLoader = new DRACOLoader();
        this.dracoLoader.setDecoderPath('https://unpkg.com/three@0.180.0/examples/jsm/libs/draco/');
        this.gltfLoader.setDRACOLoader(this.dracoLoader);
        
        // 其他格式加载器
        this.fbxLoader = new FBXLoader();
        this.objLoader = new OBJLoader();
        this.plyLoader = new PLYLoader();
        
        // 缓存系统
        this.loadedModels = new Map();
        this.loadingPromises = new Map();
        
        // 支持的文件格式
        this.supportedFormats = {
            '.gltf': 'gltf',
            '.glb': 'gltf',
            '.fbx': 'fbx',
            '.obj': 'obj',
            '.ply': 'ply'
        };
    }

    /**
     * 加载3D模型（支持多种格式）
     * @param {string} url - 模型文件URL
     * @param {Object} options - 加载选项
     * @returns {Promise<Object>} 加载的模型数据
     */
    async loadModel(url, options = {}) {
        try {
            // 检查是否已经在加载中
            if (this.loadingPromises.has(url)) {
                console.log(`模型 ${url} 正在加载中，等待完成...`);
                return await this.loadingPromises.get(url);
            }
            
            // 检查缓存
            if (this.loadedModels.has(url) && !options.forceReload) {
                console.log(`从缓存加载模型: ${url}`);
                const cachedData = this.loadedModels.get(url);
                return this.cloneModel(cachedData);
            }
            
            console.log(`开始加载模型: ${url}`);
            
            // 检测文件格式
            const format = this.detectFileFormat(url);
            if (!format) {
                throw new Error(`不支持的文件格式: ${url}`);
            }

            // 创建加载Promise时传入url
            const loadingPromise = this.createLoadPromise(url, format, {...options, url});
            this.loadingPromises.set(url, loadingPromise);
            
            try {
                const result = await loadingPromise;
                
                // 缓存结果
                if (result && !options.noCache) {
                    this.loadedModels.set(url, result);
                    console.log(`模型已缓存: ${url}`);
                }
                
                return result;
                
            } finally {
                // 清除加载Promise
                this.loadingPromises.delete(url);
            }
            
        } catch (error) {
            console.error(`模型加载失败: ${url}`, error);
            this.loadingPromises.delete(url);
            throw error;
        }
    }

    /**
     * 检测文件格式
     * @param {string} url - 文件URL
     * @returns {string|null} 文件格式
     */
    detectFileFormat(url) {
        const extension = url.toLowerCase().substring(url.lastIndexOf('.'));
        return this.supportedFormats[extension] || null;
    }

    /**
     * 带预处理的加载方法
     */
    async performLoadWithPreprocessing(url, options) {
        // 检测文件格式
        const format = this.detectFileFormat(url);
        if (!format) {
            throw new Error(`不支持的文件格式: ${url}`);
        }
        
        const loader = this.getLoader(format);
        const rawData = await this.loadWithLoader(loader, url, options);
        const processedData = await this.processLoadedData(rawData, format, options);
        
        // 预处理模型以减少渲染时的计算
        await this.preprocessModel(processedData);
        
        return processedData;
    }

    /**
     * 预处理模型
     */
    async preprocessModel(modelData) {
        if (!modelData || !modelData.model) return;
        
        const model = modelData.model;
        
        // 预计算边界盒
        const box = new THREE.Box3().setFromObject(model);
        modelData.boundingBox = box;
        
        // 预设置材质属性以避免运行时计算
        model.traverse((child) => {
            if (child.isMesh) {
                // 确保几何体已计算边界球
                if (child.geometry && !child.geometry.boundingSphere) {
                    child.geometry.computeBoundingSphere();
                }
                
                // 预设置材质
                if (child.material) {
                    const materials = Array.isArray(child.material) ? child.material : [child.material];
                    materials.forEach(material => {
                        // 确保材质已编译
                        material.needsUpdate = true;
                        
                        // 预设置透明度支持
                        if (!material.transparent) {
                            material.transparent = true;
                            material.opacity = 1.0;
                        }
                    });
                }
            }
        });
        
        console.log('模型预处理完成');
    }

    /**
     * 创建加载Promise
     * @param {string} url - 文件URL
     * @param {string} format - 文件格式
     * @param {Object} options - 加载选项
     * @returns {Promise} 加载Promise
     */
    createLoadPromise(url, format, options) {
        return new Promise((resolve, reject) => {
            const onLoad = (data) => {
                try {
                    const modelData = this.processLoadedData(data, format, options);
                    // 确保模型名称已设置
                    if (!modelData.model.name && options.url) {
                        const fileName = options.url.substring(options.url.lastIndexOf('/') + 1);
                        const modelName = fileName.split('.')[0];
                        modelData.model.name = modelName;
                        modelData.modelName = modelName;
                    }
                    this.loadedModels.set(url, modelData);
                    this.loadingPromises.delete(url);
                    resolve(this.cloneModel(modelData));
                } catch (error) {
                    console.error('模型处理失败:', error);
                    this.loadingPromises.delete(url);
                    reject(error);
                }
            };

            const onProgress = (progress) => {
                if (options.onProgress) {
                    options.onProgress(progress);
                }
            };

            const onError = (error) => {
                console.error(`${format.toUpperCase()}模型加载失败:`, error);
                this.loadingPromises.delete(url);
                reject(error);
            };

            // 根据格式选择加载器
            switch (format) {
                case 'gltf':
                    this.gltfLoader.load(url, onLoad, onProgress, onError);
                    break;
                case 'fbx':
                    this.fbxLoader.load(url, onLoad, onProgress, onError);
                    break;
                case 'obj':
                    this.objLoader.load(url, onLoad, onProgress, onError);
                    break;
                case 'ply':
                    this.plyLoader.load(url, onLoad, onProgress, onError);
                    break;
                default:
                    reject(new Error(`不支持的格式: ${format}`));
            }
        });
    }

    /**
     * 处理加载的数据
     * @param {Object} data - 加载的原始数据
     * @param {string} format - 文件格式
     * @param {Object} options - 处理选项
     * @returns {Object} 处理后的模型数据
     */
    processLoadedData(data, format, options) {
        let model, animations = [];

        switch (format) {
            case 'gltf':
                model = data.scene;
                animations = data.animations || [];
                break;
            case 'fbx':
                model = data;
                animations = data.animations || [];
                break;
            case 'obj':
                model = data;
                break;
            case 'ply':
                // PLY通常是几何体，需要创建网格
                const geometry = data;
                const material = new THREE.MeshStandardMaterial({ 
                    color: options.color || 0xffffff,
                    vertexColors: geometry.hasAttribute('color')
                });
                model = new THREE.Mesh(geometry, material);
                break;
            default:
                throw new Error(`无法处理格式: ${format}`);
        }
        
        // 确保options包含url用于提取模型名称
        const processOptions = { ...options };
        
        // 在确定model变量后设置模型名称
        if (options.url && model) {
            const fileName = options.url.substring(options.url.lastIndexOf('/') + 1);
            const modelName = fileName.split('.')[0];
            model.name = modelName;
            console.log(`在processLoadedData中设置模型名称: ${modelName}`);
        }
        
        return this.processModel({ scene: model, animations }, processOptions);
    }

    /**
     * 识别模型中的根骨骼节点或关键变换节点
     * @param {THREE.Object3D} model - 3D模型对象
     * @returns {THREE.Object3D|null} 识别出的根节点或null
     */
    identifyRootNode(model) {
        // 1. 首先检查是否有骨架节点
        let skeletonRoot = null;
        let hasSkeleton = false;
        
        model.traverse((child) => {
            // 检查是否有骨骼相关的网格
            if (child.isMesh && child.skeleton) {
                hasSkeleton = true;
                // 获取骨架的第一个骨骼作为参考
                if (child.skeleton.bones && child.skeleton.bones.length > 0) {
                    // 尝试找到这个骨骼的最顶层父节点
                    let current = child.skeleton.bones[0];
                    while (current.parent && current.parent !== model) {
                        current = current.parent;
                    }
                    skeletonRoot = current;
                }
            }
            
            // 检查是否有名为'skeleton'、'root'或'bones'的节点
            const name = child.name.toLowerCase();
            if (!skeletonRoot && (name.includes('skeleton') || name.includes('root') || name.includes('bones'))) {
                skeletonRoot = child;
            }
        });
        
        // 如果找到骨骼根节点，返回它
        if (skeletonRoot) {
            console.log(`找到骨架根节点: ${skeletonRoot.name}`);
            return skeletonRoot;
        }
        
        // 如果模型有骨骼但没找到明确的根节点，返回模型本身
        if (hasSkeleton) {
            console.log('模型包含骨骼但未找到明确根节点，返回模型本身');
            return model;
        }
        
        // 默认返回模型本身
        return model;
    }

    /**
     * 检查并禁用可能覆盖位置设置的默认动画
     * @param {Array} animations - 动画数组
     * @param {Object} options - 选项
     * @returns {Array} 处理后的动画数组
     */
    processAnimations(animations, options = {}) {
        if (!animations || animations.length === 0) {
            return [];
        }
        
        // 如果明确要求禁用所有动画
        if (options.disableAllAnimations) {
            console.log('已禁用所有动画');
            return [];
        }
        
        // 如果要求禁用位置相关动画
        if (options.disablePositionAnimations) {
            console.log('检查并禁用位置相关动画');
            const processedAnimations = animations.filter(animation => {
                const name = animation.name.toLowerCase();
                // 过滤掉明显是位置相关的动画
                if (name.includes('position') || name.includes('translate') || name.includes('move')) {
                    console.log(`跳过位置相关动画: ${animation.name}`);
                    return false;
                }
                return true;
            });
            return processedAnimations;
        }
        
        return animations;
    }

    /**
     * 为骨骼动画模型设置位置的专门方法
     * @param {THREE.Object3D} model - 3D模型对象
     * @param {THREE.Vector3|Object} position - 目标位置
     * @returns {boolean} 是否成功设置位置
     */
    setSkeletalModelPosition(model, position) {
        if (!position) return false;
        
        // 转换位置为Vector3
        const targetPos = position.isVector3 ? position : new THREE.Vector3(
            position.x || 0,
            position.y || 0,
            position.z || 0
        );
        
        // 识别根节点
        const rootNode = this.identifyRootNode(model);
        
        // 应用位置变换到根节点
        rootNode.position.copy(targetPos);
        console.log(`已将位置 ${targetPos.x}, ${targetPos.y}, ${targetPos.z} 应用到节点: ${rootNode.name}`);
        
        // 确保模型的世界矩阵被更新
        rootNode.updateMatrixWorld(true);
        
        return true;
    }

    /**
     * 处理加载的模型
     * @param {Object} gltf - GLTF数据
     * @param {Object} options - 处理选项
     * @returns {Object} 处理后的模型数据
     */
    processModel(gltf, options = {}) {
        const model = gltf.scene;
        let animations = gltf.animations;
        
        // 从URL提取模型名称，确保与配置文件中的模型名称保持一致
        if (options.url) {
            // 提取文件名（不包含扩展名）作为模型名称
            const fileName = options.url.substring(options.url.lastIndexOf('/') + 1);
            const modelName = fileName.split('.')[0];
            model.name = modelName;
            console.log(`设置模型名称为: ${modelName}`);
        }
        
        // 设置模型属性
        model.traverse((child) => {
            if (child.isMesh) {
                child.castShadow = options.castShadow !== false;
                child.receiveShadow = options.receiveShadow !== false;
                
                // 确保材质正确设置
                if (child.material) {
                    if (Array.isArray(child.material)) {
                        child.material.forEach(mat => this.setupMaterial(mat, options));
                    } else {
                        this.setupMaterial(child.material, options);
                    }
                }
            }
        });

        // 设置模型缩放
        if (options.scale) {
            model.scale.setScalar(options.scale);
        }
        
        // 处理动画
        animations = this.processAnimations(animations, options);
        
        // 检查是否是骨骼动画模型
        let isSkeletalModel = false;
        model.traverse((child) => {
            if (child.isMesh && child.skeleton) {
                isSkeletalModel = true;
            }
        });
        
        // 根据模型类型设置位置
        if (options.position) {
            if (isSkeletalModel) {
                console.log('检测到骨骼动画模型，使用专门的位置设置方法');
                this.setSkeletalModelPosition(model, options.position);
            } else {
                console.log('使用标准位置设置方法');
                model.position.copy(options.position);
            }
        }
        
        // 设置旋转
        if (options.rotation) {
            if (isSkeletalModel) {
                const rootNode = this.identifyRootNode(model);
                rootNode.rotation.copy(options.rotation);
            } else {
                model.rotation.copy(options.rotation);
            }
        }

        return {
            model,
            animations,
            mixer: null,
            actions: new Map(),
            currentAction: null,
            modelName: model.name, // 保存模型名称
            isSkeletalModel: isSkeletalModel, // 标记是否为骨骼动画模型
            rootNode: isSkeletalModel ? this.identifyRootNode(model) : null // 保存根骨骼节点
        };
    }

    /**
     * 设置材质属性
     * @param {THREE.Material} material - 材质对象
     * @param {Object} options - 选项
     */
    setupMaterial(material, options) {
        if (material.isMeshStandardMaterial || material.isMeshPhysicalMaterial) {
            // 确保材质在不同光照条件下都能正常显示
            material.envMapIntensity = options.envMapIntensity || 0.5; // 降低默认值
            material.roughness = material.roughness !== undefined ? material.roughness : 0.7;
            material.metalness = material.metalness !== undefined ? material.metalness : 0.1;
            
            // 优化纹理设置
            this.optimizeTextures(material);
        }
        
        // 设置材质的其他属性
        if (options.transparent !== undefined) {
            material.transparent = options.transparent;
        }
        
        if (options.opacity !== undefined) {
            material.opacity = options.opacity;
        }
        
        // 禁用不必要的特性以提升性能
        if (!options.enableVertexColors) {
            material.vertexColors = false;
        }
    }
    
    /**
     * 优化纹理设置
     * @param {THREE.Material} material - 材质对象
     */
    optimizeTextures(material) {
        const textureProperties = ['map', 'normalMap', 'roughnessMap', 'metalnessMap', 'aoMap', 'emissiveMap'];
        
        textureProperties.forEach(prop => {
            if (material[prop]) {
                const texture = material[prop];
                
                // 设置纹理过滤
                texture.minFilter = THREE.LinearMipmapLinearFilter;
                texture.magFilter = THREE.LinearFilter;
                
                // 启用各向异性过滤（适度）
                texture.anisotropy = Math.min(4, this.renderer?.capabilities?.getMaxAnisotropy() || 4);
                
                // 设置纹理包装
                texture.wrapS = THREE.RepeatWrapping;
                texture.wrapT = THREE.RepeatWrapping;
                
                // 生成mipmap
                texture.generateMipmaps = true;
                
                // 标记需要更新
                texture.needsUpdate = true;
            }
        });
        
        // 对于高分辨率纹理，考虑降低分辨率
        this.compressTextures(material);
    }
    
    /**
     * 压缩纹理以提升性能
     * @param {THREE.Material} material - 材质对象
     */
    compressTextures(material) {
        const maxTextureSize = 1024; // 最大纹理尺寸
        
        ['map', 'normalMap', 'roughnessMap', 'metalnessMap'].forEach(prop => {
            if (material[prop] && material[prop].image) {
                const texture = material[prop];
                const image = texture.image;
                
                // 如果纹理过大，创建缩小版本
                if (image.width > maxTextureSize || image.height > maxTextureSize) {
                    this.resizeTexture(texture, maxTextureSize);
                }
            }
        });
    }
    
    /**
     * 调整纹理尺寸
     * @param {THREE.Texture} texture - 纹理对象
     * @param {number} maxSize - 最大尺寸
     */
    resizeTexture(texture, maxSize) {
        const image = texture.image;
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');
        
        // 计算新尺寸
        const scale = Math.min(maxSize / image.width, maxSize / image.height);
        canvas.width = Math.floor(image.width * scale);
        canvas.height = Math.floor(image.height * scale);
        
        // 绘制缩小的图像
        ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
        
        // 更新纹理
        texture.image = canvas;
        texture.needsUpdate = true;
        
        console.log(`纹理已压缩: ${image.width}x${image.height} -> ${canvas.width}x${canvas.height}`);
    }

    /**
     * 克隆模型（用于创建多个实例）
     * @param {Object} modelData - 原始模型数据
     * @returns {Object} 克隆的模型数据
     */
    cloneModel(modelData) {
        const clonedModel = modelData.model.clone();
        
        // 克隆动画
        const clonedAnimations = modelData.animations.map(clip => clip.clone());
        
        return {
            model: clonedModel,
            animations: clonedAnimations,
            mixer: null,
            actions: new Map(),
            currentAction: null,
            isSkeletalModel: modelData.isSkeletalModel || false
        };
    }

    /**
     * 预加载多个模型
     * @param {Array} urls - 模型URL数组
     * @param {Object} options - 加载选项
     * @returns {Promise<Array>} 加载结果数组
     */
    async preloadModels(urls, options = {}) {
        const promises = urls.map(url => this.loadModel(url, options));
        return Promise.allSettled(promises);
    }

    /**
     * 加载场景文件（专门用于环境场景）
     * @param {string} url - 场景文件URL
     * @param {Object} options - 加载选项
     * @returns {Promise<Object>} 场景数据
     */
    async loadScene(url, options = {}) {
        const sceneOptions = {
            ...options,
            isScene: true,
            receiveShadow: options.receiveShadow !== false,
            castShadow: options.castShadow !== false
        };

        const modelData = await this.loadModel(url, sceneOptions);
        
        // 场景特殊处理
        if (modelData.model) {
            this.optimizeSceneModel(modelData.model, sceneOptions);
        }

        return modelData;
    }

    /**
     * 加载角色模型（专门用于3D角色）
     * @param {string} url - 角色模型URL
     * @param {Object} options - 加载选项
     * @returns {Promise<Object>} 角色数据
     */
    async loadCharacter(url, options = {}) {
        const characterOptions = {
            ...options,
            isCharacter: true,
            castShadow: options.castShadow !== false,
            receiveShadow: options.receiveShadow !== false,
            enableAnimations: options.enableAnimations !== false,
            disablePositionAnimations: true // 默认禁用可能影响位置的动画
        };

        const modelData = await this.loadModel(url, characterOptions);
        
        // 角色特殊处理
        if (modelData.model) {
            this.optimizeCharacterModel(modelData.model, characterOptions);
        }

        return modelData;
    }

    /**
     * 优化场景模型
     * @param {THREE.Object3D} model - 场景模型
     * @param {Object} options - 优化选项
     */
    optimizeSceneModel(model, options) {
        model.traverse((child) => {
            if (child.isMesh) {
                // 场景通常接收阴影但不投射阴影
                child.receiveShadow = options.receiveShadow !== false;
                child.castShadow = options.castShadow === true;

                // 优化材质
                if (child.material) {
                    if (Array.isArray(child.material)) {
                        child.material.forEach(mat => this.optimizeSceneMaterial(mat));
                    } else {
                        this.optimizeSceneMaterial(child.material);
                    }
                }

                // 设置渲染层级
                child.renderOrder = 0;
            }
        });
    }

    /**
     * 优化角色模型
     * @param {THREE.Object3D} model - 角色模型
     * @param {Object} options - 优化选项
     */
    optimizeCharacterModel(model, options) {
        model.traverse((child) => {
            if (child.isMesh) {
                // 角色通常投射阴影
                child.castShadow = options.castShadow !== false;
                child.receiveShadow = options.receiveShadow !== false;

                // 优化材质
                if (child.material) {
                    if (Array.isArray(child.material)) {
                        child.material.forEach(mat => this.optimizeCharacterMaterial(mat));
                    } else {
                        this.optimizeCharacterMaterial(child.material);
                    }
                }

                // 设置渲染层级（角色在场景之上）
                child.renderOrder = 1;
            }

            // 处理骨骼
            if (child.isBone) {
                child.visible = false; // 隐藏骨骼可视化
            }
        });

        // 设置角色默认位置和朝向
        model.position.y = 0;
        model.rotation.y = 0;
    }

    /**
     * 优化场景材质
     * @param {THREE.Material} material - 材质
     */
    optimizeSceneMaterial(material) {
        if (material.isMeshStandardMaterial || material.isMeshPhysicalMaterial) {
            // 场景材质优化
            material.envMapIntensity = material.envMapIntensity || 0.3; // 进一步降低
            material.roughness = material.roughness !== undefined ? material.roughness : 0.8;
            material.metalness = material.metalness !== undefined ? material.metalness : 0.05;
            
            // 禁用不必要的特性
            if (!material.transparent) {
                material.alphaTest = 0;
            }
            
            // 优化阴影
            material.shadowSide = THREE.FrontSide;
        }
        
        // 优化纹理
        this.optimizeTextures(material);
    }

    /**
     * 优化角色材质
     * @param {THREE.Material} material - 材质
     */
    optimizeCharacterMaterial(material) {
        if (material.isMeshStandardMaterial || material.isMeshPhysicalMaterial) {
            // 角色材质优化
            material.envMapIntensity = material.envMapIntensity || 0.2; // 降低反射强度
            material.roughness = material.roughness !== undefined ? material.roughness : 0.6;
            material.metalness = material.metalness !== undefined ? material.metalness : 0.0;
            
            // 启用顶点颜色（如果有）
            if (material.geometry && material.geometry.hasAttribute('color')) {
                material.vertexColors = true;
            }
            
            // 优化皮肤材质
            if (material.name && material.name.toLowerCase().includes('skin')) {
                material.roughness = 0.4;
                material.metalness = 0.0;
                material.envMapIntensity = 0.1;
            }
        }
        
        // 优化纹理
        this.optimizeTextures(material);
    }
    
    /**
     * 创建LOD版本的模型
     * @param {THREE.Object3D} model - 原始模型
     * @param {Object} options - LOD选项
     * @returns {THREE.LOD} LOD对象
     */
    createLODModel(model, options = {}) {
        const lod = new THREE.LOD();
        
        // 高细节级别（原始模型）
        lod.addLevel(model, 0);
        
        // 中等细节级别
        if (options.createMediumLOD !== false) {
            const mediumModel = this.createSimplifiedModel(model, 0.6);
            lod.addLevel(mediumModel, options.mediumDistance || 50);
        }
        
        // 低细节级别
        if (options.createLowLOD !== false) {
            const lowModel = this.createSimplifiedModel(model, 0.3);
            lod.addLevel(lowModel, options.lowDistance || 100);
        }
        
        return lod;
    }
    
    /**
     * 创建简化版本的模型
     * @param {THREE.Object3D} model - 原始模型
     * @param {number} quality - 质量级别 (0-1)
     * @returns {THREE.Object3D} 简化的模型
     */
    createSimplifiedModel(model, quality) {
        const simplified = model.clone();
        
        simplified.traverse((child) => {
            if (child.isMesh) {
                // 简化几何体
                if (child.geometry && child.geometry.attributes.position) {
                    child.geometry = this.simplifyGeometry(child.geometry, quality);
                }
                
                // 简化材质
                if (child.material) {
                    child.material = this.simplifyMaterial(child.material, quality);
                }
            }
        });
        
        return simplified;
    }
    
    /**
     * 简化几何体
     * @param {THREE.BufferGeometry} geometry - 原始几何体
     * @param {number} quality - 质量级别
     * @returns {THREE.BufferGeometry} 简化的几何体
     */
    simplifyGeometry(geometry, quality) {
        // 这里可以实现几何体简化算法
        // 目前返回原始几何体，实际项目中可以使用SimplifyModifier
        const simplified = geometry.clone();
        
        // 降低顶点密度（简单实现）
        if (quality < 0.5 && simplified.index) {
            const indexArray = simplified.index.array;
            const newIndexArray = new indexArray.constructor(Math.floor(indexArray.length * quality));
            
            for (let i = 0; i < newIndexArray.length; i++) {
                newIndexArray[i] = indexArray[Math.floor(i / quality)];
            }
            
            simplified.setIndex(new THREE.BufferAttribute(newIndexArray, 1));
        }
        
        return simplified;
    }
    
    /**
     * 简化材质
     * @param {THREE.Material} material - 原始材质
     * @param {number} quality - 质量级别
     * @returns {THREE.Material} 简化的材质
     */
    simplifyMaterial(material, quality) {
        const simplified = material.clone();
        
        // 根据质量级别移除一些贴图
        if (quality < 0.7) {
            simplified.aoMap = null;
            simplified.lightMap = null;
        }
        
        if (quality < 0.5) {
            simplified.normalMap = null;
            simplified.roughnessMap = null;
            simplified.metalnessMap = null;
        }
        
        if (quality < 0.3) {
            // 使用简单的颜色替代纹理
            if (simplified.map) {
                simplified.color.copy(simplified.map.image ? 
                    this.getAverageColor(simplified.map) : 
                    new THREE.Color(0.8, 0.8, 0.8)
                );
                simplified.map = null;
            }
        }
        
        return simplified;
    }
    
    /**
     * 获取纹理的平均颜色
     * @param {THREE.Texture} texture - 纹理
     * @returns {THREE.Color} 平均颜色
     */
    getAverageColor(texture) {
        // 简单实现，返回中性灰色
        // 实际项目中可以分析纹理像素
        return new THREE.Color(0.7, 0.7, 0.7);
    }

    /**
     * 批量加载场景和角色
     * @param {Object} config - 加载配置
     * @returns {Promise<Object>} 加载结果
     */
    async loadSceneWithCharacters(config) {
        const results = {
            scene: null,
            characters: new Map(),
            errors: []
        };

        try {
            // 加载场景
            if (config.sceneUrl) {
                console.log('加载场景:', config.sceneUrl);
                results.scene = await this.loadScene(config.sceneUrl, config.sceneOptions || {});
            }

            // 加载角色
            if (config.characters && Array.isArray(config.characters)) {
                const characterPromises = config.characters.map(async (charConfig) => {
                    try {
                        const characterData = await this.loadCharacter(
                            charConfig.url, 
                            charConfig.options || {}
                        );
                        results.characters.set(charConfig.id, characterData);
                        console.log(`角色加载完成: ${charConfig.id}`);
                    } catch (error) {
                        console.error(`角色加载失败 ${charConfig.id}:`, error);
                        results.errors.push({ type: 'character', id: charConfig.id, error });
                    }
                });

                await Promise.all(characterPromises);
            }

            console.log('场景和角色加载完成');
            return results;

        } catch (error) {
            console.error('场景加载失败:', error);
            results.errors.push({ type: 'scene', error });
            return results;
        }
    }

    /**
     * 清理缓存
     * @param {string} url - 要清理的模型URL，不传则清理所有
     */
    clearCache(url = null) {
        if (url) {
            this.loadedModels.delete(url);
            this.loadingPromises.delete(url);
        } else {
            this.loadedModels.clear();
            this.loadingPromises.clear();
        }
    }

    /**
     * 获取模型的边界框
     * @param {THREE.Object3D} model - 模型对象
     * @returns {THREE.Box3} 边界框
     */
    getModelBounds(model) {
        const box = new THREE.Box3().setFromObject(model);
        return box;
    }

    /**
     * 居中模型
     * @param {THREE.Object3D} model - 模型对象
     */
    centerModel(model) {
        const box = this.getModelBounds(model);
        const center = box.getCenter(new THREE.Vector3());
        model.position.sub(center);
    }

    /**
     * 缩放模型到指定大小
     * @param {THREE.Object3D} model - 模型对象
     * @param {number} targetSize - 目标大小
     * @returns {number} 应用的缩放因子
     */
    scaleModelToSize(model, targetSize) {
        // 计算模型边界盒
        const box = this.getModelBounds(model);
        const size = box.getSize(new THREE.Vector3());
        
        // 计算缩放比例
        const maxDimension = Math.max(size.x, size.y, size.z);
        const scaleFactor = targetSize / maxDimension;
        
        // 应用缩放
        model.scale.setScalar(scaleFactor);
        
        return scaleFactor;
    }
    
    /**
     * 验证模型名称一致性的辅助方法
     * 用于测试模型名称是否正确从URL提取
     * @param {string} url - 模型URL
     * @returns {string} 预期的模型名称
     */
    getExpectedModelName(url) {
        if (!url) return null;
        const fileName = url.substring(url.lastIndexOf('/') + 1);
        const modelName = fileName.split('.')[0];
        console.log(`从URL ${url} 提取的预期模型名称: ${modelName}`);
        return modelName;
    }
    
    /**
     * 为已加载的模型重新设置位置
     * @param {Object} modelData - 模型数据
     * @param {THREE.Vector3|Object} position - 新位置
     * @returns {boolean} 是否成功设置
     */
    repositionModel(modelData, position) {
        if (!modelData || !modelData.model || !position) {
            console.error('无效的模型数据或位置参数');
            return false;
        }
        
        if (modelData.isSkeletalModel) {
            console.log('为骨骼动画模型重新设置位置');
            return this.setSkeletalModelPosition(modelData.model, position);
        } else {
            console.log('为标准模型重新设置位置');
            modelData.model.position.set(
                position.x || 0,
                position.y || 0,
                position.z || 0
            );
            return true;
        }
    }
}

export class AnimationController {
    constructor(modelData, clock) {
        this.modelData = modelData;
        this.clock = clock;
        this.mixer = null;
        this.actions = new Map();
        this.currentAction = null;
        this.isPlaying = false;
        
        this.setupAnimations();
    }

    /**
     * 设置动画系统
     */
    setupAnimations() {
        if (this.modelData.animations && this.modelData.animations.length > 0) {
            this.mixer = new THREE.AnimationMixer(this.modelData.model);
            
            // 创建所有动画动作
            this.modelData.animations.forEach((clip, index) => {
                const action = this.mixer.clipAction(clip);
                const name = clip.name || `animation_${index}`;
                this.actions.set(name, action);
            });
            
            this.modelData.mixer = this.mixer;
            this.modelData.actions = this.actions;
        }
    }

    /**
     * 播放指定动画
     * @param {string} animationName - 动画名称
     * @param {Object} options - 播放选项
     */
    playAnimation(animationName, options = {}) {
        if (!this.mixer || !this.actions.has(animationName)) {
            console.warn(`动画 "${animationName}" 不存在`);
            return;
        }

        const action = this.actions.get(animationName);
        
        // 停止当前动画
        if (this.currentAction && this.currentAction !== action) {
            if (options.crossFade) {
                this.currentAction.crossFadeTo(action, options.crossFadeDuration || 0.5, true);
            } else {
                this.currentAction.stop();
            }
        }

        // 设置动画属性
        action.reset();
        action.setLoop(options.loop !== false ? THREE.LoopRepeat : THREE.LoopOnce);
        action.clampWhenFinished = options.clampWhenFinished || false;
        
        if (options.timeScale !== undefined) {
            action.setEffectiveTimeScale(options.timeScale);
        }
        
        if (options.weight !== undefined) {
            action.setEffectiveWeight(options.weight);
        }

        // 播放动画
        action.play();
        this.currentAction = action;
        this.isPlaying = true;

        // 设置动画结束回调
        if (options.onFinished) {
            const onFinished = () => {
                options.onFinished();
                this.mixer.removeEventListener('finished', onFinished);
            };
            this.mixer.addEventListener('finished', onFinished);
        }
    }

    /**
     * 停止当前动画
     */
    stopAnimation() {
        if (this.currentAction) {
            this.currentAction.stop();
            this.currentAction = null;
            this.isPlaying = false;
        }
    }

    /**
     * 暂停/恢复动画
     */
    toggleAnimation() {
        if (this.currentAction) {
            if (this.isPlaying) {
                this.currentAction.paused = true;
                this.isPlaying = false;
            } else {
                this.currentAction.paused = false;
                this.isPlaying = true;
            }
        }
    }

    /**
     * 获取所有可用的动画名称
     * @returns {Array<string>} 动画名称数组
     */
    getAnimationNames() {
        return Array.from(this.actions.keys());
    }

    /**
     * 检查动画是否存在
     * @param {string} animationName - 动画名称
     * @returns {boolean} 是否存在
     */
    hasAnimation(animationName) {
        return this.actions.has(animationName);
    }

    /**
     * 更新动画（在渲染循环中调用）
     */
    update() {
        if (this.mixer) {
            const delta = this.clock.getDelta();
            this.mixer.update(delta);
        }
    }

    /**
     * 设置动画速度
     * @param {number} speed - 速度倍数
     */
    setAnimationSpeed(speed) {
        if (this.currentAction) {
            this.currentAction.setEffectiveTimeScale(speed);
        }
    }

    /**
     * 获取当前动画进度
     * @returns {number} 进度（0-1）
     */
    getAnimationProgress() {
        if (this.currentAction) {
            const duration = this.currentAction.getClip().duration;
            return this.currentAction.time / duration;
        }
        return 0;
    }

    /**
     * 设置动画进度
     * @param {number} progress - 进度（0-1）
     */
    setAnimationProgress(progress) {
        if (this.currentAction) {
            const duration = this.currentAction.getClip().duration;
            this.currentAction.time = progress * duration;
        }
    }

    /**
     * 混合多个动画
     * @param {Array} animations - 动画配置数组
     */
    blendAnimations(animations) {
        animations.forEach(({ name, weight }) => {
            if (this.actions.has(name)) {
                const action = this.actions.get(name);
                action.setEffectiveWeight(weight);
                if (!action.isRunning()) {
                    action.play();
                }
            }
        });
    }

    /**
     * 清理动画控制器
     */
    dispose() {
        if (this.mixer) {
            this.mixer.stopAllAction();
            this.mixer.uncacheRoot(this.modelData.model);
        }
        this.actions.clear();
        this.currentAction = null;
        this.isPlaying = false;
    }
}